package com.example.taluo.utils.redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Tuple;

import java.util.Set;

/*** @Author supersaiya
 * @Description Jedis 操作工具类

 * @Date 2025/2/17 21:34

 * @Version 1.0*/
public class RedisUtil {

    private static JedisPool jedisPool;

    // 静态初始化：创建 Jedis 连接池
    static {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(128); // 最大连接数
        poolConfig.setMaxIdle(64);   // 最大空闲连接数
        poolConfig.setMinIdle(16);   // 最小空闲连接数
        poolConfig.setTestOnBorrow(true); // 在获取连接时检查有效性

        // 创建连接池，连接到 Redis 服务
        jedisPool = new JedisPool(poolConfig, "localhost", 6379);  // 根据需要修改主机和端口
    }

    // 获取 Jedis 实例
    private static Jedis getJedis() {
        return jedisPool.getResource();
    }

    // 释放 Jedis 实例
    private static void returnResource(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    // 设置键值对
    public static void set(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.set(key, value);
        } catch (Exception e) {
            System.err.println("Error setting value: " + e.getMessage());
        } finally {
            returnResource(jedis);
        }
    }

    // 获取键值对
    public static String get(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.get(key);
        } catch (Exception e) {
            System.err.println("Error getting value: " + e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    // 删除键
    public static void del(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.del(key);
        } catch (Exception e) {
            System.err.println("Error deleting key: " + e.getMessage());
        } finally {
            returnResource(jedis);
        }
    }

    // 判断键是否存在
    public static boolean exists(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.exists(key);
        } catch (Exception e) {
            System.err.println("Error checking key existence: " + e.getMessage());
            return false;
        } finally {
            returnResource(jedis);
        }
    }

    // 设置带过期时间的键值对
    public static void setEx(String key, String value, int seconds) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.setex(key, seconds, value);
        } catch (Exception e) {
            System.err.println("Error setting value with expiration: " + e.getMessage());
        } finally {
            returnResource(jedis);
        }
    }

    // 获取键的过期时间
    public static long ttl(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.ttl(key);
        } catch (Exception e) {
            System.err.println("Error getting TTL: " + e.getMessage());
            return -1;
        } finally {
            returnResource(jedis);
        }
    }

    // 添加元素到列表左侧
    public static void lpush(String listKey, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.lpush(listKey, value);
        } catch (Exception e) {
            System.err.println("Error pushing value to list: " + e.getMessage());
        } finally {
            returnResource(jedis);
        }
    }

    // 从列表右侧弹出元素
    public static String rpop(String listKey) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.rpop(listKey);
        } catch (Exception e) {
            System.err.println("Error popping value from list: " + e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    // --- 哈希操作 ---
    public static void hset(String key, String field, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.hset(key, field, value);
        } catch (Exception e) {
            System.err.println("Error setting hash field: " + e.getMessage());
        } finally {
            returnResource(jedis);
        }
    }

    public static String hget(String key, String field) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hget(key, field);
        } catch (Exception e) {
            System.err.println("Error getting hash field: " + e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    public static void hdel(String key, String field) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.hdel(key, field);
        } catch (Exception e) {
            System.err.println("Error deleting hash field: " + e.getMessage());
        } finally {
            returnResource(jedis);
        }
    }

    public static Long hincrBy(String key, String field, long value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hincrBy(key, field, value);
        } catch (Exception e) {
            System.err.println("Error incrementing hash field: " + e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    public static Long hlen(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hlen(key);
        } catch (Exception e) {
            System.err.println("Error getting hash length: " + e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    // --- 集合操作 ---
    public static void sadd(String key, String member) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.sadd(key, member);
        } catch (Exception e) {
            System.err.println("Error adding member to set: " + e.getMessage());
        } finally {
            returnResource(jedis);
        }
    }

    public static Long srem(String key, String member) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.srem(key, member);
        } catch (Exception e) {
            System.err.println("Error removing member from set: " + e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    public static Boolean sismember(String key, String member) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.sismember(key, member);
        } catch (Exception e) {
            System.err.println("Error checking membership: " + e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    public static Long scard(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.scard(key);
        } catch (Exception e) {
            System.err.println("Error getting set size: " + e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    public static Set<String> smembers(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.smembers(key);
        } catch (Exception e) {
            System.err.println("Error getting set members: " + e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }
    // --- ZSET 操作封装 ---

    /**
     * 添加或更新成员及其分数
     * @param key          ZSET 的键
     * @param member       成员
     * @param score        分数
     */
    public static void zadd(String key, double score, String member) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.zadd(key, score, member);
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 增加成员的分数
     * @param key          ZSET 的键
     * @param member       成员
     * @param increment    分数增量
     */
    public static void zincrby(String key, double increment, String member) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.zincrby(key, increment, member);
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 获取成员的分数
     * @param key          ZSET 的键
     * @param member       成员
     * @return             成员的分数，如果不存在返回 null
     */
    public static Double zscore(String key, String member) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.zscore(key, member);
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 获取成员的排名（从高到低）
     * @param key          ZSET 的键
     * @param member       成员
     * @return             成员的排名，从 1 开始，如果不存在返回 -1
     */
    public static long zrevrank(String key, String member) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            Long rank = jedis.zrevrank(key, member);
            return rank == null ? -1 : rank + 1; // 排名从 0 开始，返回时加 1
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 获取前 N 名成员及其分数
     * @param key          ZSET 的键
     * @param topN         获取前 N 名
     * @return             包含成员及其分数的集合
     */
    public static Set<Tuple> zrevrangeWithScores(String key, int topN) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.zrevrangeWithScores(key, 0, topN - 1);
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 获取前 N 名成员（仅成员名）
     * @param key          ZSET 的键
     * @param topN         获取前 N 名
     * @return             包含成员名的集合
     */
    public static Set<String> zrevrange(String key, int topN) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.zrevrange(key, 0, topN - 1);
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 从 ZSET 中移除成员
     * @param key          ZSET 的键
     * @param member       成员
     */
    public static void zrem(String key, String member) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.zrem(key, member);
        } finally {
            returnResource(jedis);
        }
    }
}